home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / quicktime / quicktime for java / timecode / src / timecode.java < prev   
Encoding:
Java Source  |  2000-06-23  |  8.5 KB  |  267 lines

  1. /*
  2.  * QuickTime for Java SDK Sample Code
  3.  
  4.    Usage subject to restrictions in SDK License Agreement
  5.  * Copyright: © 1996-1999 Apple Computer, Inc.
  6.  
  7.     Special Thanks to Darren Gibbs <darreng@cinebase.com> for the TimeCodeMedia code
  8.  */
  9.  
  10. import java.awt.*;
  11. import java.awt.event.*;
  12.  
  13. import quicktime.*;
  14. import quicktime.io.*;
  15. import quicktime.qd.*;
  16. import quicktime.std.*;
  17. import quicktime.std.image.*;
  18. import quicktime.std.movies.*;
  19. import quicktime.std.movies.media.*;
  20. import quicktime.std.qtcomponents.*;
  21. import quicktime.util.*;
  22. import quicktime.app.display.QTCanvas;
  23. import quicktime.app.players.QTPlayer;
  24.  
  25. public class TimeCode extends Frame {    
  26.     
  27.     public static void main (String args[]) {
  28.         try {
  29.             QTSession.open ();            
  30.             TimeCode tc = new TimeCode("QT in Java");
  31.                 // this will lay out and resize the Frame to the size of the Movie
  32.             tc.pack();
  33.             tc.show();
  34.             tc.toFront();
  35.         } catch (QTException e) {
  36.                 // catch a userCanceledErr and just exit the program
  37.             if (e.errorCode() == Errors.userCanceledErr) {
  38.                 QTSession.close();
  39.                 System.exit(0);
  40.             }
  41.                 // some other error occured - print out a stack trace
  42.                 // and close the QTSession
  43.             e.printStackTrace();
  44.             QTSession.close();
  45.         }
  46.     }
  47.  
  48.     TimeCode (String title) throws QTException {
  49.         super (title);
  50.         setResizable (false);
  51.         
  52.             // prompt the user to select a movie file
  53.         qtf = QTFile.standardGetFilePreview(QTFile.kStandardQTFileTypes);
  54.             
  55.             // open the selected file and make a Movie from it
  56.         OpenMovieFile movieFile = OpenMovieFile.asRead(qtf);
  57.         theMovie = Movie.fromFile (movieFile);
  58.             
  59.             // make a MovieController from the resultant Movie
  60.             // enabling the keys so the user can interact with the movie with the keyboard
  61.         mc = new MovieController (theMovie);
  62.         mc.setKeysEnabled (true);
  63.             
  64.             // make a QTCanvas so that the MovieController has somewhere to draw
  65.             // and add it to the Frame
  66.         myQTCanvas = new QTCanvas();
  67.         add (myQTCanvas);
  68.         
  69.             // make the QTDrawable object to present a MovieController
  70.         QTPlayer myQTPlayer = new QTPlayer (mc);
  71.         
  72.             // Set it as the drawing client of the QTCanvas
  73.             // for a QTPlayer this will also register interests
  74.             // for both Mouse and Key events that originate in the QTCanvas            
  75.         myQTCanvas.setClient (myQTPlayer, true);
  76.         
  77.             // add a file menu to add/remove time code to the movie
  78.         new FileMenu (this);
  79.  
  80.             // add a Window Listener to this frame 
  81.             // that will close down the QTSession, dispose of the Frame
  82.             // which will close the window - where we exit
  83.         addWindowListener(new WindowAdapter () {
  84.             public void windowClosing (WindowEvent e) {
  85.                 QTSession.close();
  86.                 dispose();
  87.             }
  88.  
  89.             public void windowClosed (WindowEvent e) { 
  90.                 System.exit(0);
  91.             }
  92.         });
  93.     }
  94.     
  95. MovieController mc;
  96. Movie theMovie;
  97. QTCanvas myQTCanvas;
  98. QTFile qtf;
  99.  
  100.     public void goAway () {
  101.         QTSession.close();
  102.         dispose();
  103.         System.exit(0);
  104.     }
  105.  
  106.     public void addTimecodeToMovie () {        
  107.         try {
  108.             Track myTrack = theMovie.getIndTrackType (1, StdQTConstants.timeCodeMediaType, 
  109.                                                         StdQTConstants.movieTrackMediaType );
  110.                 //only allow one time code track in movie
  111.             if (myTrack != null) 
  112.                 return;
  113.  
  114.  
  115.             // Get the (first) visual track; this track determines the width of the new timecode track
  116.             Track theVisualTrack = theMovie.getIndTrackType (1, StdQTConstants.visualMediaCharacteristic, 
  117.                                                             StdQTConstants.movieTrackCharacteristic );
  118.             
  119.             Dimension dim = null;
  120.             // Get movie and track attributes
  121.             int movieTimeScale = theMovie.getTimeScale();
  122.  
  123.                 // Create the timecode track and media
  124.             if (theVisualTrack == null) {
  125.                  QDRect r = mc.getBounds();
  126.                  dim = new Dimension (r.getWidth(), r.getHeight());
  127.             } else {
  128.                 Media theVisualTrackMedia = Media.fromTrack (theVisualTrack);
  129.                 dim = theVisualTrack.getDimensions();
  130.             }
  131.             
  132.             Track theTCTrack = theMovie.newTrack ((float)dim.width, (float)dim.height, 0);            
  133.             TimeCodeMedia theTCMedia = new TimeCodeMedia (theTCTrack, movieTimeScale);
  134.             TimeCoder theTimeCoder = theTCMedia.getTimeCodeHandler();
  135.  
  136.             // Set up a TimeCodeDef
  137.             TimeCodeDef    myTCDef = new TimeCodeDef();
  138.                 //30 frames a second time code reading
  139.             int tcdFlags = StdQTConstants.tc24HourMax;
  140.             myTCDef.setFlags (tcdFlags);
  141.             myTCDef.setTimeScale (3000);
  142.             myTCDef.setFrameDuration (100);
  143.             myTCDef.setFramesPerSecond (30);
  144.             /*
  145.                 For drop frame 29.97 fps
  146.                 tcdFlags |= StdQTConstants.tcDropFrame;
  147.                 myTCDef.setTimeScale (2997);
  148.             */
  149.             // Start the timecode at 0:0:0:0
  150.             TimeCodeTime myTCTime = new TimeCodeTime (0, 0, 0, 0);
  151.  
  152.             // Change the text options to Green on Black.
  153.             String myTCString = theTimeCoder.timeCodeToString (myTCDef, myTCTime);
  154.             TCTextOptions myTCTextOptions = theTimeCoder.getDisplayOptions();
  155.             int textSize = myTCTextOptions.getTXSize();
  156.             myTCTextOptions.setForeColor (QDColor.green);
  157.             myTCTextOptions.setBackColor (QDColor.black);
  158.             theTimeCoder.setDisplayOptions (myTCTextOptions);
  159.  
  160.         // Figure out the timecode track geometry
  161.             Dimension tcDim = theTCTrack.getDimensions();
  162.             tcDim.height = textSize + 2;
  163.             theTCTrack.setDimensions (tcDim);
  164.             if (dim.height > 0) {
  165.                 Matrix TCMatrix = theTCTrack.getMatrix();
  166.                 TCMatrix.translate (0, dim.height);
  167.                 theTCTrack.setMatrix (TCMatrix);
  168.             }
  169.                                     
  170.             // add a sample to the timecode track
  171.             //
  172.             // each sample in a timecode track provides timecode information for a span of movie time;
  173.             // here, we add a single sample that spans the entire movie duration
  174.  
  175.             // the sample data contains a frame number that identifies one or more content frames
  176.             // that use the timecode; this value (a long integer) identifies the first frame that
  177.             // uses the timecode.  For our purposes this will probably always be zero, but it can't
  178.             // hurt to go the full 9.
  179.             int frameNumber = theTimeCoder.toFrameNumber (myTCTime, myTCDef);
  180.             int[] frameNumberAr = { frameNumber };
  181.             QTHandle myFrameNumHandle = new QTHandle (4, false);
  182.             myFrameNumHandle.copyFromArray (0, frameNumberAr, 0, 1);
  183.  
  184.             // create and configure a new timecode description
  185.             TimeCodeDescription myTCDescription = new TimeCodeDescription ();
  186.             myTCDescription.setTimeCodeDef (myTCDef);            
  187.  
  188.             // edit the track media
  189.             theTCMedia.beginEdits();    
  190.             
  191.                 // since we created the track with the same timescale as the movie,
  192.                 // we don't need to convert the duration
  193.                 theTCMedia.addSample (myFrameNumHandle, 
  194.                                         0, 
  195.                                         myFrameNumHandle.getSize(), 
  196.                                         theMovie.getDuration(), 
  197.                                         myTCDescription, 
  198.                                         1, 
  199.                                         0);
  200.             theTCMedia.endEdits();    
  201.             
  202.             theTCTrack.insertMedia (0, 0, theMovie.getDuration(), 1.0F);
  203.             
  204.             // this code saves the TimeCode to the movie
  205.         /*
  206.             OpenMovieFile outStream = OpenMovieFile.asWrite (qtf); 
  207.             theMovie.addResource (outStream, movieInDataForkResID, qtf.getName());
  208.             outStream.close();
  209.         */
  210.         
  211.             // Make the timecode visible
  212.             int tcFlags = theTimeCoder.getFlags();
  213.             tcFlags |= StdQTConstants.tcdfShowTimeCode;
  214.             theTimeCoder.setFlags (tcFlags, StdQTConstants.tcdfShowTimeCode);
  215.             
  216.             changedMovie ();
  217.         } catch (QTException err) {
  218.             err.printStackTrace();
  219.         }
  220.     }
  221.  
  222.     public void deleteTimeCodeTracks () {
  223.         try {
  224.             Track myTrack = null;
  225.             do {
  226.                 myTrack = theMovie.getIndTrackType (1, StdQTConstants.timeCodeMediaType, 
  227.                                                         StdQTConstants.movieTrackMediaType );
  228.                 if (myTrack != null) 
  229.                     theMovie.removeTrack( myTrack );
  230.  
  231.             } while (myTrack != null);
  232.             
  233.             // if you previous saved the time code to the movie
  234.             // removing the time code track you also need to update the movie file
  235.         /*
  236.             OpenMovieFile outStream = OpenMovieFile.asWrite (qtf); 
  237.             theMovie.addResource (outStream, movieInDataForkResID, qtf.getName());
  238.             outStream.close();
  239.         */
  240.             
  241.             changedMovie();
  242.         } catch (QTException err) {
  243.             err.printStackTrace();
  244.         }
  245.     }
  246.     
  247.     private void changedMovie () throws QTException {
  248.         // tell the controller that we have changed the movie
  249.         mc.movieChanged();
  250.         
  251.         // tell the QTCanvas that we have changed the MovieController/QTPlayer client's actual size
  252.         // this is a different size because we've added the time code to the bottom of the movie
  253.         QDRect mcRect = mc.getBounds();
  254.         myQTCanvas.clientChanged (mcRect.getWidth(), mcRect.getHeight());
  255.         myQTCanvas.invalidate();
  256.         
  257.         // this will resize the frame to the current (new) size of the movie
  258.         // the QTCanvas will be resized as a result of this call
  259.         pack();
  260.     }
  261. }
  262.  
  263.  
  264.  
  265.  
  266.  
  267.